<!DOCTYPE html>
<html lang="en" xml:lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Analog ROI</title>

    <style>
        #reboot_button {
            float: none;
            background-color: #f44336;
            color: white;
            padding: 5px;
            border-radius:
            5px; font-weight: bold;
            text-align: center;
            text-decoration: none;
            display: inline-block;
        }
    </style>

    <link href="edit_style.css" rel="stylesheet">
    <link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">

    <script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
    <script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
    <script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>

</head>

<body style="font-family: arial; padding: 0px 10px;">

    <h2>Analog ROI</h2>
    <details id="desc_details" style="font-size:16px">
        <summary><b>CLICK HERE</b> for usage description. More infos in documentation: 
            <a href=https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/ target=_blank>ROI Configuration</a>
        </summary>
        <p>
            <b>R</b>egion <b>O</b>f <b>I</b>nterest (ROI) for analog pointer counter can be defined on this page. If no analog pointer counter need to be 
            processed, disable analog pointer counter processing by deselecting <b>"Analog ROI Processing"</b>.
        </p>
        <p>
            By default one number sequence (a number seqence contains of 1-x digit ROIs + 1-x analog counter ROIs which are processed together) is 
            predefined and already selected in the drop down <b>"Number Sequence"</b>. If you need more than one number sequence additional
            one's can be added with the buttons next to the drop down. Each number sequence will be processed separately.
        </p>
        <p>
            Using drag and drop by mouse of by manually entering the parameters into the given fields the analog ROIs can be positined to the analog pointer
            counters on the reference image. To have proper ROI definition please check the documentation: 
            <a href=https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/ target=_blank>ROI Configuration</a>. It's very important to be
            really precise to have reliable processing. With the drop down <b>"ROI"</b> you can change between the different ROIs in the selected
            number sequence. To create new ROIs use <b>"New ROI"</b>.
        </p>
        <p>
            The order of the ROIs defines the position (and therefore the multiplication factor) within the reading sequence. The position
            in the number sequence can be changed with the buttons <b>"Move ROI Lower"</b> and <b>"Move ROI Higher"</b>. The multiplication factor which is
            shown below the ROI drop down is the multiplication factor of pure position/order in number sequence and the factor right-hand side to this is 
            the additionally corrected by decimal shift setting (configuration, expert parameter, default: 0). 
        </p>
        <p>
            After definition of digit ROIs is completed don't forget to save with the <b>"Save Config"</b> button!<br>
            <b>NOTE:</b> There is no need to perform a reboot after every saving or step. It's sufficient to reboot after all configuration steps 
            (reference image, alignment, ROI configuration) are completed to activate new configuration.
        </p>
    </details>
    <hr />

    <p>   
        <input type="checkbox" id="Category_Analog_enabled" value="1"  onclick = 'EnDisableAnalog()' checked >
            <label style="font-weight: bold; font-size: larger;" for="Category_Analog_enabled">Analog ROI Processing</label>
    </p>


<div id="div1">
    <table>
        <colgroup>
            <col span="1" style="width: 22%;">
            <col span="1" style="width: 26%;">
            <col span="1" style="width: 26%;">
            <col span="1" style="width: 26%;">
        </colgroup>
		
        <tr>
            <td colspan="4" style="padding: 0px"><class id="Numbers_text" style="color:black;">Number Sequence:</class></td>
        </tr>
		
        <tr>
            <td>
                <select id="Numbers_value1" onchange="numberChanged()">
                </select>
            </td>
            <td><input class="button" type="submit" id="newNumber" name="newNumber" onclick="newNumber()" value="New Sequence"></td>
            <td><input class="button" type="submit" id="renameNumber" name="renameNumber" onclick="renameNumber()" value="Rename Sequence"></td> 
            <td><input class="button" type="submit" id="removeNumber" name="removeNumber" onclick="removeNumber()" value="Delete Sequence"></td>
        </tr>
    </table>

    <hr />

    <table>
        <colgroup>
            <col span="1" style="width: 22%;">
            <col span="1" style="width: 26%;">
            <col span="1" style="width: 26%;">
            <col span="1" style="width: 26%;">
        </colgroup>
		
        <tr>
            <td style="padding: 0px">ROI:</td>
        </tr>
		
        <tr>
            <td><select id="index" name="index" onchange="ChangeSelection()" tabindex=1></select></td>
            <td><input class="button" type="submit" id="newROI" name="newROI" onclick="newROI()" value="New ROI"></td>
            <td><input class="button" type="submit" id="renameROI" name="renameROI" onclick="renameROI()" value="Rename ROI"></td>	  
            <td><input class="button" type="submit" id="deleteROI" name="deleteROI" onclick="deleteROI()" value="Delete ROI"></td>
        </tr>
		
        <tr>       
            <td class="multiplier">Multiplier: <output type="text" id="multiplier" name="multiplier"></output><br>
                (only based on order)
            </td>
            <td class="multiplier">Multiplier: <output type="text" id="multiplier_decshift" name="multiplier_decshift"></output><br>
                (order + decimal shift: <output type="text" id="decimalShift" name="decimalShift"></output>)
            </td>
            <td><input class="button" type="submit" id="movePrevious" onclick="movePrevious()" value="Move ROI Higher"></td> 
            <td><input class="button" type="submit" id="moveNext" onclick="moveNext()" value="Move ROI Lower"></td>
        </tr>
    </table>

	<table>
        <colgroup>
            <col span="1" style="width: 18%;">
            <col span="1" style="width: 18%;">
            <col span="1" style="width: 64%;">
        </colgroup>
		
        <tr>
            <td>x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()" tabindex=2></td>	  
            <td>Δx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchangeddx()" tabindex=4></td>
        </tr>
		
        <tr>
            <td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()" tabindex=3></td>	
            <td>Δy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()" tabindex=5></td>
        </tr>
		
        <tr>
            <td colspan="3"><input type="checkbox" id="CCW" name="CCW" value="0" onclick="changeCCW()" unchecked tabindex=8><label for="CCW">Counter clockwise rotation (CCW)</label></td>
        </tr>		
    </table>		 
</div>

<hr>
The following settings are only used for easier setup, they are <b>not</b> persisted on the device:<br>
<input type="checkbox" id="showall" name="showall" value="1" onclick="draw()" checked tabindex=9><label for="showall"> Show all ROIs</label><br>
<input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio </label><br>
<input type="checkbox" id="lockSizes" name="lockSizes" value="1" onclick="changelockSizes()" checked tabindex=7><label for="lockSizes"> Synchronize y, Δx and Δy between ROIs</label><br>
<hr>

    <table>
        <colgroup>
            <col span="1" style="width: 22%;">
            <col span="1" style="width: 26%;">
            <col span="1" style="width: 26%;">
            <col span="1" style="width: 26%;">
        </colgroup>
		
        <tr>
            <td colspan="3" style="vertical-align: bottom;"><b>Reference Image:</b></td>
            <td>
				<input style="font-weight:bold;" class="button" type="submit" id="saveroi" name="saveroi" onclick="SaveToConfig()" value="Save Config" tabindex=10>
			</td>
        </tr>
		
        <tr>
            <td colspan="4"><canvas id="canvas" crossorigin></canvas></td>
        </tr>
    </table>


<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>

<script type="text/javascript">
    var canvas = document.getElementById('canvas'),
        ctx = canvas.getContext('2d'),
        imageObj = new Image(),
        rect = {},
        drag = false,
        aktindex = 0,
        ROIInfo,
        cofcat,
        param,
        _roialt = "ana",
        enhanceCon = false,
        lockAspectRatio = true,
        lockSizes = false,
        domainname = getDomainname();

    function doReboot() {
        var stringota = getDomainname() + "/reboot";
        window.location = stringota;
        window.location.href = stringota;
        window.location.assign(stringota);
        window.location.replace(stringota);
    }
    
    function EnDisableAnalog() {
        isEnabled = document.getElementById("Category_Analog_enabled").checked;

        $("#div2").attr("disabled", "disabled").off('click');
        var x1=$("#div2").hasClass("disabledDiv");
        
        if (isEnabled) {
            $("#div2").removeClass("disabledDiv");
        }
        else {
            $("#div2").addClass("disabledDiv");
        }
		
        sah1(document.getElementById("div1"), !isEnabled);

        cofcat["Analog"]["enabled"] = isEnabled;
        document.getElementById("saveroi").disabled = false;
                
        if (isEnabled) {
            UpdateROIs();
        }
    }

    function sah1(el, _target) {
        try {
            el.disabled = _target;
        } catch (E) {}
	    
        if (el.childNodes && el.childNodes.length > 0) {
            for (var x = 0; x < el.childNodes.length; x++) {
                sah1(el.childNodes[x], _target);
            }
        }
    }

    function onNameChange() {
        ROIInfo[aktindex]["name"] = document.getElementById("name").value;
        UpdateROIs();
    }

    function deleteROI() {
        if (!confirm("Delete the selected ROI?")) {
            return; //break out of the function early because prompt was aborted
        }

        ROIInfo.splice(aktindex, 1);
	    
        if (aktindex > ROIInfo.length - 1){
            aktindex = ROIInfo.length - 1;
        }
	    
        UpdateROIs();
        draw();
    }

    function newROI() {
        var sel = document.getElementById("Numbers_value1");
        var _number= sel.options[sel.selectedIndex].text;
        sel = document.getElementById("index");
	
        if (ROIInfo.length > 0) {
            _roialt = sel.options[sel.selectedIndex].text;
        }
        else {
            _roialt = "ana";
        }

        var _roinew = prompt("Please enter a name for the new ROI", _roialt);
	
        if (_roinew === null) {
            return; //break out of the function early because prompt was aborted
        }

        if (ROIInfo.length > 0) {
            erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 15, 30, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], ROIInfo[aktindex]["CCW"]=="true");
        }
        else {
            erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 15, 30, 30, 30, false);
        }

        if (erg != "") {
            firework.launch(erg, 'danger', 30000);
        }
        else {
            UpdateROIs(_roinew);
        }
    }

    function movePrevious() {
        var zw = ROIInfo[aktindex];
        ROIInfo[aktindex] = ROIInfo[aktindex-1];
        ROIInfo[aktindex-1] = zw;
        aktindex--;
        UpdateROIs();      
    }

    function moveNext() {
        var zw = ROIInfo[aktindex];
        ROIInfo[aktindex] = ROIInfo[aktindex+1];
        ROIInfo[aktindex+1] = zw;
        aktindex++;
        UpdateROIs();    
    }

    function changelockAspectRatio() {
        lockAspectRatio = document.getElementById("lockAspectRatio").checked;
    }

    function changelockSizes() {
        lockSizes = document.getElementById("lockSizes").checked;
        UpdateROIs(); 
    }

    function changeCCW() {
        var sel = document.getElementById("Numbers_value1");
        var _number = sel.options[sel.selectedIndex].text;

        ROIInfo = getROIInfo("analog", _number);
        aktindex = parseInt(document.getElementById("index").value);

        if (document.getElementById("CCW").checked) {
            ROIInfo[aktindex]["CCW"] = "true";
        }
        else {
            ROIInfo[aktindex]["CCW"] = "false";
        }
	
        UpdateROIs();
    }

    function ChangeSelection() {
        aktindex = parseInt(document.getElementById("index").value);
        // lockAspectRatio = true;
        UpdateROIs();
    }

    function SaveToConfig() {
        //_zwcat = getConfigCategory();
        cofcat["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked;
        WriteConfigININew();
        SaveConfigToServer(domainname);
        UpdateROIs();
        document.getElementById("saveroi").disabled = true;

        firework.launch('Configuration saved. It will get applied after the next reboot!<br><br>\n<a id="reboot_button" onclick="doReboot()">reboot now</a>', 'success', 5000);
    }

    function ShowMultiplier() {
        var decimalShift = 0;
        var multiplier;
        var multiplier_decshift;
        var fixedDecimals;
        var fixedDecimals_decshift;
        var NumberInfo = getNUMBERInfo();
        var CategoryInfo = getConfigCategory();

        var sel = document.getElementById("Numbers_value1");
        var _number= sel.options[sel.selectedIndex].text;
        document.getElementById("decimalShift").value = 0;
        
        for (var i = 0; i < NumberInfo.length; ++i) {
            if (NumberInfo[i]["name"] == _number) {
                if (NumberInfo[i]["PostProcessing"]["DecimalShift"]["enabled"]) {
                    decimalShift = NumberInfo[i]["PostProcessing"]["DecimalShift"]["value1"];
                    document.getElementById("decimalShift").value=decimalShift;  
                } 
            }
        }

        if (CategoryInfo["Analog"]["enabled"] == true && CategoryInfo["Digits"]["enabled"] == true) { // Digit + Analog
            multiplier = fixedDecimals = aktindex + 1;
            multiplier_decshift = fixedDecimals_decshift = multiplier - Number(decimalShift);

            if (multiplier < 0) {
                fixedDecimals = 0;
            }

            if (multiplier_decshift < 0) {
                fixedDecimals_decshift = 0;
            }

            document.getElementById("multiplier").value="x" + Number(10 ** (-1*multiplier)).toFixed(fixedDecimals);
            document.getElementById("multiplier_decshift").value="x" + Number(10 ** (-1*multiplier_decshift)).toFixed(fixedDecimals_decshift);
        }
        else if (CategoryInfo["Analog"]["enabled"] == true && CategoryInfo["Digits"]["enabled"] == false) { // Only Analog
            multiplier = ROIInfo.length - 1 - aktindex;
            multiplier_decshift = fixedDecimals_decshift = multiplier + Number(decimalShift);
        
            if (multiplier_decshift > 0) {
                fixedDecimals_decshift = 0;
            }
        
            if (fixedDecimals_decshift < 0) {
                fixedDecimals_decshift = -1 * fixedDecimals_decshift;
            }

            document.getElementById("multiplier").value="x" + Number(10 ** multiplier).toFixed(0);
            document.getElementById("multiplier_decshift").value="x" + Number(10 ** multiplier_decshift).toFixed(fixedDecimals_decshift);
        }
    }


    function UpdateROIs(_sel){
        document.getElementById("Category_Analog_enabled").checked = true;
        var sel = document.getElementById("Numbers_value1");
        var _number = sel.options[sel.selectedIndex].text;

        ROIInfo = getROIInfo("analog", _number);
        // _catzw = getConfigCategory();

        if (cofcat["Analog"]["enabled"] == false) {
            document.getElementById("Category_Analog_enabled").checked = false;
            EnDisableAnalog();
            firework.launch('Analog ROI processing is disabled. Activate with checkbox if needed', 'warning', 10000);
            return;
        }

        if (ROIInfo.length == 0){
            firework.launch('No analog ROIs defined in selected number sequence', 'warning', 10000);
            document.getElementById("newROI").disabled = false;
            document.getElementById("deleteROI").disabled = true;
            document.getElementById("renameROI").disabled = true;
            document.getElementById("index").disabled = true;
            document.getElementById("multiplier").style.display = "none";
            document.getElementById("multiplier_decshift").style.display = "none";
            document.getElementById("refx").disabled = true;
            document.getElementById("refdx").disabled = true;
            document.getElementById("refy").disabled = true;
            document.getElementById("refdy").disabled = true;
            document.getElementById("lockSizes").disabled = true;
            document.getElementById("showall").disabled = true;    
            document.getElementById("lockAspectRatio").disabled = true;
            document.getElementById("CCW").disabled = true;
            document.getElementById("moveNext").disabled = true;
            document.getElementById("movePrevious").disabled = true;
            document.getElementById("saveroi").disabled = false;
            return;
        }
        else {
            document.getElementById("newROI").disabled = false;
            document.getElementById("deleteROI").disabled = false;
            document.getElementById("renameROI").disabled = false;
            document.getElementById("index").disabled = false;
            document.getElementById("multiplier").style.display = "";
            document.getElementById("multiplier_decshift").style.display = "";
            document.getElementById("refx").disabled = false;
            document.getElementById("refdx").disabled = false;
            document.getElementById("refy").disabled = false;
            document.getElementById("refdy").disabled = false;
            document.getElementById("lockSizes").disabled = false;
            document.getElementById("showall").disabled = false;    
            document.getElementById("lockAspectRatio").disabled = false;
            document.getElementById("CCW").disabled = false;
            document.getElementById("saveroi").disabled = false;
        }

        var _index = document.getElementById("index");
        while (_index.length){
            _index.remove(0);
        }

        if (aktindex > ROIInfo.length) {
            aktindex = ROIInfo.length-1;
        }

        for (var i = 0; i < ROIInfo.length; ++i){
            var option = document.createElement("option");
            option.text = ROIInfo[i]["name"];
            option.value = i;
            _index.add(option);
            if (typeof _sel !== 'undefined') {
                if (option.text == _sel) {
                    aktindex = i;
                }
            }
        }
	
        _index.selectedIndex = aktindex; 

        document.getElementById("movePrevious").disabled = false;
        if (aktindex == 0){
            document.getElementById("movePrevious").disabled = true;
        }

        document.getElementById("moveNext").disabled = false;
        if (aktindex == (ROIInfo.length-1)){
            document.getElementById("moveNext").disabled = true;
        }
	
        ShowMultiplier();
    
        document.getElementById("lockAspectRatio").checked = lockAspectRatio;
        document.getElementById("lockSizes").checked = lockSizes;
       
        document.getElementById("refx").value = ROIInfo[aktindex]["x"];
        document.getElementById("refy").value = ROIInfo[aktindex]["y"];  
        document.getElementById("refdx").value = ROIInfo[aktindex]["dx"];  
        document.getElementById("refdy").value = ROIInfo[aktindex]["dy"];  
        document.getElementById("CCW").checked = ROIInfo[aktindex]["CCW"] == "true";

        rect.startX = ROIInfo[aktindex]["x"];
        rect.startY = ROIInfo[aktindex]["y"];
        rect.w = ROIInfo[aktindex]["dx"];
        rect.h = ROIInfo[aktindex]["dy"];
        draw();
    }
    
    function loadCanvas(dataURL) {
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');
    
        imageObj.onload = function() {
            canvas.width = this.width;
            canvas.height = this.height;
            drawImage();
            draw();
        };
    
        imageObj.src = dataURL;
    }
    
    function getCoords(elem) { 
        // crossbrowser version
        var box = elem.getBoundingClientRect();
        var body = document.body;
        var docEl = document.documentElement;
        var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
        var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
        var clientTop = docEl.clientTop || body.clientTop || 0;
        var clientLeft = docEl.clientLeft || body.clientLeft || 0;
        var top  = box.top +  scrollTop - clientTop;
        var left = box.left + scrollLeft - clientLeft;
        return { top: Math.round(top), left: Math.round(left) };
    }

    /* hash #description open the details part of the page */
    function openDescription() {
        if(window.location.hash) {
            var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
            if(hash == 'description') {
                document.getElementById("desc_details").open = false;
            }
        }
    }
    
    function init() {
        openDescription();
        domainname = getDomainname();
		
		if (!loadConfig(domainname)) {
			firework.launch('Configuration could not be loaded! Please reload the page!', 'danger', 30000);
			return;
		}
	
        ParseConfig();
        param = getConfigParameters(); 
        cofcat = getConfigCategory();
		
        canvas.addEventListener('mousedown', mouseDown, false);
        canvas.addEventListener('mouseup', mouseUp, false);
        canvas.addEventListener('mousemove', mouseMove, false);
        loadCanvas(domainname + "/fileserver/config/reference.jpg");		
		
        UpdateNUMBERS();

        /* Check if the ROIs have same dy and dx. If so, tick the sync checkbox */
        var all_dx_dy_Identical = true;
		
        if (ROIInfo.length > 1) {
            for (var i = 1; i < (ROIInfo.length); ++i) { // 2nd .. last ROI
                if (parseInt(ROIInfo[i].dx) != parseInt(ROIInfo[0].dx) || parseInt(ROIInfo[i].dy) != parseInt(ROIInfo[0].dy)) { 
                    all_dx_dy_Identical = false;
                    break;
                }
            }
        }

        if (all_dx_dy_Identical) {
            lockSizes = true;
            console.log("All ROI have the same dX and dY, ticking the sync checkbox!");
            document.getElementById("lockSizes").checked = lockSizes;
        }
        else {
            console.log("Not all ROI have the same dX and dY, unticking the sync checkbox!");
        }

        document.getElementById("saveroi").disabled = true;

        drawImage();
        draw();
    }

    function drawImage(){
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');

        context.clearRect(0,0,imageObj.width,imageObj.height);
        context.save();
        context.drawImage(imageObj, 0, 0);
        // context.restore();
    }  

    function UpdateNUMBERS(_sel) {
        zw = getNUMBERInfo();
        index = 0;

        var _index = document.getElementById("Numbers_value1");
        while (_index.length){
            _index.remove(0);
        }

        for (var i = 0; i < zw.length; ++i){
            var option = document.createElement("option");
            option.text = zw[i]["name"];
            option.value = i;
            _index.add(option); 

            if (typeof _sel !== 'undefined') {
                if (zw[i]["name"] == _sel) {
                   index = i;
                }
            }
        }
        _index.selectedIndex = index;

        UpdateROIs();
    }

    function renameNumber() {
        var sel = document.getElementById("Numbers_value1");
        var _delete= sel.options[sel.selectedIndex].text;
        var _numbernew = prompt("Please enter a new name for the selected number sequence", _delete);
        if (_numbernew === null) {
            return; //break out of the function early because prompt was aborted
        }

        erg = RenameNUMBER(_delete, _numbernew);
	    
        if (erg != "") {
            firework.launch(erg, 'danger', 30000);
        }
        else {
            UpdateNUMBERS(_numbernew);
        }
    }

    function newNumber() {
        var _numbernew = prompt("Please enter a name for the new number sequence", "name");
        if (_numbernew === null) {
            return; //break out of the function early because prompt was aborted
        }

        erg = CreateNUMBER(_numbernew);
	    
        if (erg != "") {
            firework.launch(erg, 'danger', 30000);
        }
        else {
            UpdateNUMBERS(_numbernew);
        }
    }

    function removeNumber() {
        if (confirm("The entire number sequence will be removed (digit + analog parts). " +
                "To remove single ROI of the number sequence, use \"Delete ROI\" instead.\n" +
                "Do you really want to proceed?")) {
            var sel = document.getElementById("Numbers_value1");
            var _delete= sel.options[sel.selectedIndex].text;
            erg = DeleteNUMBER(_delete);
            if (erg != "") {
                firework.launch(erg, 'danger', 30000);
            }
            UpdateNUMBERS();
        }	    
    }

    function drawTextBG(context, txt, x, y, padding) {
        context.font = "15px Arial";
        context.textAlign = "center";

        context.fillStyle = 'rgba(255, 0, 0, 0.5)';
        var width = context.measureText(txt).width;
        context.fillRect(x-(width+padding)/2, y-12, width + padding*2, parseInt(context.font, 10) + padding);

        context.fillStyle = "black";
        context.fillText(txt, x + padding / 2, y + padding / 2);
    }

    function draw() {
        if (typeof ROIInfo === 'undefined') { 
            // During init, ROIInfo is not defined yet
            return;
        }
    
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');
        context.drawImage(imageObj, 0, 0);

        if (ROIInfo.length == 0) {
            return;
        } 

        context.font = "15px Arial";
        context.fillStyle = "red";
        context.textAlign = "center";

        if (document.getElementById("Category_Analog_enabled").checked) {
            var sel = document.getElementById("index");
            var _number = sel.selectedIndex;

            if (lockSizes) {
                // Synchronize dx and dy
                for (var _nb = 0; _nb < ROIInfo.length; _nb++) {
                    if (_nb != _number) {
                        ROIInfo[_nb].dy = rect.h;
                        ROIInfo[_nb].dx = rect.w;
                    }
                }
            }

            if (document.getElementById("showall").checked) {		
                for (var _nb = 0; _nb < ROIInfo.length; _nb++) {
                    if (_nb != _number) {
                        lw = 2;
                        context.lineWidth = lw;
                        context.strokeStyle = "#990000";
                        var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
                        var y0 = parseInt(ROIInfo[_nb].y) - parseInt(lw/2);
                        var dx = parseInt(ROIInfo[_nb].dx) + parseInt(lw);
                        var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
                        context.strokeRect(x0, y0, dx, dy);
                    
                        if (ROIInfo[_nb]["CCW"] != "true") {
                           drawTextBG(context, ROIInfo[_nb]["name"], x0+dx/2-0.5, y0-13, 5);
                        }
                        else {
                           drawTextBG(context, ROIInfo[_nb]["name"]+" (CCW)", x0+dx/2-0.5, y0-13, 5);
                        }
                    
                        lw = 1;
                        var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
                        var y0 = parseInt(ROIInfo[_nb].y) - parseInt(lw/2);
                        var dx = parseInt(ROIInfo[_nb].dx) + parseInt(lw);
                        var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
                        context.strokeRect(x0, y0, dx, dy); 
                        context.lineWidth = lw;
                        context.beginPath();
                        // context.arc (x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI);
                        context.ellipse(x0+dx/2, y0+dy/2, dx/2, dy/2, 0, 0, 2 * Math.PI);
                        context.moveTo(x0+dx/2, y0);
                        context.lineTo(x0+dx/2, y0+dy);
                        context.moveTo(x0, y0+dy/2);
                        context.lineTo(x0+dx, y0+dy/2);
                        context.stroke();  
                    }
                }
            }

            lw = 4
            context.lineWidth = lw;
            context.strokeStyle = "#FF0000";
            var x0 = parseInt(rect.startX) - parseInt(lw/2);
            var y0 = parseInt(rect.startY) - parseInt(lw/2);
            var dx = parseInt(rect.w) + parseInt(lw);
            var dy = parseInt(rect.h) + parseInt(lw);
            context.strokeRect(x0, y0, dx, dy);

            if (ROIInfo[aktindex]["CCW"] != "true") {
                drawTextBG(context, ROIInfo[aktindex]["name"], x0+dx/2, y0-11, 5);
            }
            else {
                drawTextBG(context, ROIInfo[aktindex]["name"] + " (CCW)", x0+dx/2, y0-11, 5);
            }

            context.lineWidth = 1;
            context.beginPath();
            // context.arc(x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI);
            context.ellipse(x0+dx/2, y0+dy/2, dx/2, dy/2, 0, 0, 2 * Math.PI);
            context.moveTo(x0+dx/2, y0);
            context.lineTo(x0+dx/2, y0+dy);
            context.moveTo(x0, y0+dy/2);
            context.lineTo(x0+dx, y0+dy/2);
            context.stroke();   
            ROIInfo[aktindex]["x"] = rect.startX;       
            ROIInfo[aktindex]["y"] = rect.startY;       
            ROIInfo[aktindex]["dx"] = rect.w;       
            ROIInfo[aktindex]["dy"] = rect.h;       
        }
    }

    function mouseDown(e) {
        zw = getCoords(this)
        rect.startX = e.pageX - zw.left;
        rect.startY = e.pageY - zw.top;
        document.getElementById("refx").value =  rect.startX;
        document.getElementById("refy").value =  rect.startY;    
        drag = true;
    }

    function mouseUp() {
        drag = false;
        if (rect.w < 0) {
            rect.w = -rect.w
            rect.startX-=rect.w
        }
        if (rect.h < 0) {
            rect.h = -rect.h
            rect.startY-=rect.h
        }
        document.getElementById("refdx").value = rect.w;
        document.getElementById("refdy").value = rect.h;
        document.getElementById("refx").value = rect.startX;
        document.getElementById("refy").value = rect.startY;    
    }

    function mouseMove(e) {
        if (drag) {
            zw = getCoords(this)        

            if (lockAspectRatio) {
                rect.h = (e.pageY - zw.top) - rect.startY;
                rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);            
            }
            else {
                rect.w = (e.pageX - zw.left) - rect.startX;
                rect.h = (e.pageY - zw.top) - rect.startY;
            }
            document.getElementById("refdx").value = rect.w;
            document.getElementById("refdy").value = rect.h;
            draw();
        }
        else {
            draw();
            var canvas = document.getElementById('canvas');
            var context = canvas.getContext('2d');

            zw = getCoords(this);
            x = e.pageX - zw.left;
            y = e.pageY - zw.top;
            
            context.lineWidth = 2;
            context.strokeStyle = "#00FF00";
            context.beginPath(); 
            context.moveTo(0,y);
            context.lineTo(canvas.width, y);
            context.moveTo(x, 0);
            context.lineTo(x, canvas.height);
            context.stroke();            
        }
    }

    function valuemanualchanged() {
        if (!drag) {
            rect.w = document.getElementById("refdx").value;
            rect.h = document.getElementById("refdy").value;
            if (lockAspectRatio) {
                rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);
                document.getElementById("refdx").value = rect.w;
            }

            rect.startX = document.getElementById("refx").value;
            rect.startY = document.getElementById("refy").value; 
            draw();            
        }
        document.getElementById("saveroi").disabled = false;
    }

    function valuemanualchangeddx() {
        if (!drag) {
            rect.w = document.getElementById("refdx").value;
            rect.h = document.getElementById("refdy").value;
            if (lockAspectRatio) {
                rect.h = Math.round(rect.w / ROIInfo[aktindex]["ar"]);
                document.getElementById("refdy").value = rect.h;
            }

            rect.startX = document.getElementById("refx").value;
            rect.startY = document.getElementById("refy").value; 
            draw();            
        }
        document.getElementById("saveroi").disabled = false;
    }

    function renameROI() {
        var sel = document.getElementById("Numbers_value1");
        var _number= sel.options[sel.selectedIndex].text;
        sel = document.getElementById("index");
        _roialt= sel.options[sel.selectedIndex].text;

        var _roinew = prompt("Please enter a new name for the selected ROI", _roialt);
        if (_roinew === null) {
            return; //break out of the function early because prompt was aborted
        }

        erg = RenameROI(_number, "analog", _roialt, _roinew);
        if (erg != "") {
            firework.launch(erg, 'danger', 30000);
        }
        else {
            UpdateROIs(_roinew);
        }
    }

    function numberChanged() {
        aktindex = 0;
        UpdateROIs();
    }    

    init();

</script>
</body>
</html>
